package com.cjst.controller.sys;


import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.cjst.controller.base.BaseController;
import com.cjst.pojo.sys.SysMenu;
import com.cjst.sdp.util.MapUtils;
import com.cjst.sdp.util.ZTreeNode;
import com.cjst.service.sys.SysMenuService;
import com.cjst.sql.C;
import com.cjst.sql.Method;
import com.cjst.sql.WherePrams;
import com.cjst.util.json.ResultObj;

/**
 * 菜单管理
 *
 * @author szbj001
 */
@Controller
@RequestMapping("/sys/sysMenu")
public class SysMenuController extends BaseController {

    @Autowired
    public SysMenuService menuService;

    /**
     * 菜单列表
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @RequiresPermissions("t_sys_menu")
    public String toMenu() {
        return "system/menu/menu";
    }

    /**
     * 跳转到添加页面
     */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    @RequiresPermissions("t_sys_menu_add")
    public String addMenu() {
        return "system/menu/menu_add";
    }

    /**
     * 跳转到修改页面
     */
    @RequestMapping(value = "/edit/{menuId}", method = RequestMethod.GET)
    @RequiresPermissions("t_sys_menu_edit")
    public String updateMenu(@PathVariable String menuId, Model model) {
        WherePrams where = Method.where("id", C.EQ, menuId);
        SysMenu menu = menuService.get(where);
        if (menu != null) {
            Map<String, Object> menuMap = MapUtils.transBean2Map(menu);
            //判断当前选择的节点是否顶层节点，如果不是，就查询上级节点
            if (!"0".equals(menu.getPcode())) {
                WherePrams wherePrams = Method.where("code", C.EQ, menu.getPcode());
                SysMenu pMenu = menuService.get(wherePrams);
                if (pMenu != null) {
                    menuMap.put("pcodeName", pMenu.getName());
                } else {
                    menuMap.put("pcodeName", "顶级");
                }
            } else {
                menuMap.put("pcodeName", "顶级");
            }
            if(menu.getIcon()!=null && menu.getIcon().length()>0){
            	menuMap.put("icon", filePath+menu.getIcon());
            }
            model.addAttribute("menu", menuMap);
        }

        return "system/menu/menu_edit";
    }

    /**
     * 菜单详情
     */
    @RequestMapping(value = "/view/{menuId}", method = RequestMethod.GET)
    @RequiresPermissions("t_sys_menu_view")
    public String menuView(@PathVariable String menuId, Model model) {
        WherePrams where = Method.where("id", C.EQ, menuId);
        SysMenu menu = menuService.get(where);
        if (menu != null) {
            Map<String, Object> menuMap = MapUtils.transBean2Map(menu);
            //判断当前选择的节点是否顶层节点，如果不是，就查询上级节点
            if (!"0".equals(menu.getPcode())) {
                WherePrams wherePrams = Method.where("code", C.EQ, menu.getPcode());
                SysMenu pMenu = menuService.get(wherePrams);
                if (pMenu != null) {
                    menuMap.put("pcodeName", pMenu.getName());
                } else {
                    menuMap.put("pcodeName", "顶级");
                }
            } else {
                menuMap.put("pcodeName", "顶级");
            }
            model.addAttribute("menu", menuMap);
        }

        return "system/menu/menu_view";
    }


    /**
     * 菜单树形列表
     */
    @RequestMapping(value = "/treeList", method = RequestMethod.POST)
    @ResponseBody
    public List<Map<String, Object>> getMenuMap(@RequestParam(required = false) String menuName,
        @RequestParam(required = false) String level) {
        List<Map<String, Object>> menus = menuService.getMenuMap(menuName, level);
        return menus;
    }

    /**
     * 点击父级编号出现菜单树形结构
     */
    @RequestMapping(value = "/selectMenuTreeList", method = RequestMethod.POST)
    @ResponseBody
    public List<ZTreeNode> selectMenuTreeList() {
        List<ZTreeNode> menuTreeList = menuService.tree();
        menuTreeList.add(ZTreeNode.createParent());
        return menuTreeList;
    }

    private void menuSetPcode(@Valid SysMenu menu) throws Exception {
        if (menu.getNum() == null) {
            menu.setNum(0);
        }
        if (StringUtils.isEmpty(menu.getPcode()) || menu.getPcode().equals("0")) {
            menu.setPcode("0");
            menu.setPcodes("[0],");
            menu.setLevels(1);
            menu.setParentId("0");
        } else {
            String code = menu.getPcode();
            WherePrams where = Method.where("id", C.EQ, code);
            SysMenu pMenu = menuService.get(where);
            if (pMenu != null) {
                //如果编号和父编号一致会导致无限递归
                if (StringUtils.isNotEmpty(menu.getCode())&&menu.getCode().equals(pMenu.getCode())) {
                    throw new Exception("菜单编号不能与菜单父编号相同");
                }
                if (StringUtils.isNotEmpty(menu.getCode())&&pMenu.getPcodes().contains(menu.getCode())) {
                    throw new Exception("上级菜单不能是当前菜单的子菜单");
                }
                Integer pLevels = pMenu.getLevels();
                menu.setPcode(pMenu.getCode());
                menu.setLevels(pLevels + 1);
                menu.setPcodes(pMenu.getPcodes() + "[" + pMenu.getCode() + "],");
                menu.setParentId(pMenu.getId());
            } else {
                throw new Exception("菜单父编号不存在");
            }
        }
        
        if(StringUtils.isNotEmpty(menu.getId())) {
        	//查询数据库的菜单信息
        	SysMenu menu2 = menuService.get(menu.getId());
        	//检查当前菜单时候有子菜单
        	WherePrams prams = Method.where("status", C.EQ, "1");
        	prams.and("pcodes", C.LIKE,menu.getCode());
        	List<SysMenu> menus = menuService.list(prams);
        	if(menus!=null&&menus.size()>0) {
        		for (SysMenu sysMenu : menus) {
					String pcodes = sysMenu.getPcodes();
					pcodes = menu.getPcodes()+pcodes.substring(pcodes.indexOf(menu2.getPcode())+menu2.getPcode().length()+1);
					sysMenu.setPcodes(pcodes);
					//
					int level =  sysMenu.getLevels();
					
					int old_lev = menu2.getLevels();
					int new_lev = menu.getLevels();
					
					int offset = new_lev - old_lev;
					
					sysMenu.setLevels(level+offset);
					
							
					menuService.updateLocal(sysMenu);
				}
        	}
        }
    }

    /**
     * 修改
     */
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("t_sys_menu_edit")
    public Object edit(@Valid SysMenu menu, BindingResult result) throws Exception {
        if (result.hasErrors()) {
            List<ObjectError> errorList = result.getAllErrors();
            for (ObjectError error : errorList) {
                log.info("ERROR:" + error.getDefaultMessage());
                return new ResultObj(1, "参数传递错误", error.getDefaultMessage());
            }

        }
        WherePrams prams =Method.where("id", C.EQ, menu.getId());
        SysMenu sysMenu = menuService.get(prams);
        if(sysMenu!=null) {
        	 //设置父级菜单编号
	        menuSetPcode(menu);
	        int flag = menuService.updateLocal(menu);
	        
	        if(!sysMenu.getCode().equals(menu.getCode())) {  //如果菜单编号改变，则需要修改子菜单的父节点编号
	        	WherePrams wherePrams = Method.where("parentId", C.EQ, menu.getId());
	        	List<SysMenu> childMenus = menuService.list(wherePrams);
	        	for (SysMenu sysMenu2 : childMenus) {
					sysMenu2.setPcode(menu.getCode());
					sysMenu2.setPcodes(menu.getPcodes() + "[" + menu.getCode() + "],");
					
					menuService.updateLocal(sysMenu2);
				}
	        }
	        log.info("=============修改菜单成功===============");
	        return new ResultObj(0, "成功", flag);
        }else {
        	return new ResultObj(1, "修改菜单异常", null);
        }
    }

    @RequestMapping(value = "/add")
    @ResponseBody
    @RequiresPermissions("t_sys_menu_add")
    public Object add(@Valid SysMenu menu, BindingResult result) throws Exception {
        if (result.hasErrors()) {
            List<ObjectError> errorList = result.getAllErrors();
            for (ObjectError error : errorList) {
                log.info("ERROR:" + error.getDefaultMessage());
                return new ResultObj(1, "参数传递错误", error.getDefaultMessage());
            }
        }

        //判断是否存在该编号
        WherePrams where = Method.where("code", C.EQ, menu.getCode());
        where.and("status", C.EQ, "1");
        SysMenu pMenu = menuService.get(where);
        if (pMenu != null) {
            return new ResultObj(1, "编号存在，无法新增", null);
        }
        //设置父级菜单编号
        menuSetPcode(menu);
        menu.setStatus("1");
        String flag = menuService.addLocalByid(menu);
        log.info("=============新增菜单成功===============");
        return new ResultObj(0, "成功", flag);
    }

    /**
     * 删除菜单
     * @param ids
     * @return
     */
    @RequestMapping(value = "/remove")
    @ResponseBody
    @RequiresPermissions("t_sys_menu_remove")
    public Object remove(String menuId) {
    	if(StringUtils.isEmpty(menuId)) {
    		return new ResultObj(1, "参数传递异常，删除失败", null);
    	}
    	SysMenu menu = menuService.get(menuId);
    	if(menu == null) {
    		return new ResultObj(1, "菜单不存在，删除异常", null);
    	}
    	
    	WherePrams wherePrams = Method.where("id", C.EQ, menuId);
    	wherePrams.or("pcodes", C.LIKE, menu.getCode());
 		SysMenu menu2 = new SysMenu();
 		menu2.setStatus("0"); //逻辑删除
		
 		int flag = menuService.updateLocal(menu2, wherePrams);
        return new ResultObj(0, "删除成功",flag);
    }
    @Value("${img.location}")
    private String fileUploadPath;
    @Value("${file.path}")
    private String filePath;
    /**
     * 上传头像
     * @param request
     * @param file
     * @return
     */
    @RequestMapping("/upload")
    @ResponseBody
    @Transactional
    public Object upload(HttpServletRequest request, MultipartFile file,String dirs) {
        try {

            //文件上传路径
            String serverPath = fileUploadPath;

            String uploadDir = "";

            //文件名称
            String fileName = file.getOriginalFilename();
            //文件后缀
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            if(dirs!=null && dirs.length()>0){
            	uploadDir = uploadDir + "/" + dirs + "/" + "avator";
            }else{
            	uploadDir = uploadDir + "/"  + "avator";
            }
            

            //检查目录是否存在
            File dir = new File(serverPath + uploadDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            //随机名称
            String randomFileName = UUID.randomUUID().toString();
            //文件存在服务器上的路径
            String fileUrl = uploadDir + "/" + randomFileName + "." + suffix;

            //将文件上传到文集的物理地址
            File serverFile = new File(serverPath + fileUrl);
            file.transferTo(serverFile);
            log.info("文件上传成功");
            HashMap<String, String> map=new HashMap<String, String>();
            map.put("fileUrl", fileUrl);
            map.put("filePath", filePath + fileUrl);
            return new ResultObj(1, "文件上传成功", map);

        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResultObj(0, e.getMessage(), null);
        }

    }
}




